﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web.Helpers;
using System.Web.Mvc;
using System.Web.UI.DataVisualization.Charting;
using LSEntity;
using LSUtility;
using Chart = System.Web.Helpers.Chart;

namespace LSBLL
{
    public static class MyChart
    {
        public static Chart GetChart<T, T1, T2>(this ChartEntity<T> chartEntity, Expression<Func<T, T1>> xField, Expression<Func<T, T2>> yField) where T : class
        {
            return GetChart<T, T1, T2, String>(chartEntity, xField, yField, null);
        }

        public static Chart GetChart<T, T1, T2, T3>(this ChartEntity<T> chartEntity, Expression<Func<T, T1>> xField, Expression<Func<T, T2>> yField, Func<T, T3> group) where T : class
        {
            var cachedChart = Chart.GetFromCache(chartEntity.CacheKey);
            if (cachedChart == null)
            {
                var sources = chartEntity.GetData();
                cachedChart = new Chart(chartEntity.Width, chartEntity.Height)
                    .AddTitle(chartEntity.Title)
                    .SetXAxis(chartEntity.XTitle)
                    .SetYAxis(chartEntity.YTitle);
                if (group != null)
                {
                    cachedChart.AddLegend("", "");
                    var groupList = sources.GroupBy(group);
                    foreach (var groupvalue in groupList)
                    {
                        var xList = new List<T1>();
                        var yList = new List<T2>();
                        foreach (var val in groupvalue)
                        {
                            xList.Add(val.GetValueFromEntity(xField));
                            yList.Add(val.GetValueFromEntity(yField));
                        }
                        cachedChart.AddSeries(groupvalue.Key.ToString(),
                                              chartEntity.ChartType.ToString(),
                                              axisLabel: xField.LamdaGetName(),
                                              xValue: xList,
                                              yValues: yList);
                    }
                }
                else
                {
                    var xList = new List<T1>();
                    var yList = new List<T2>();
                    foreach (var source in sources)
                    {
                        xList.Add(source.GetValueFromEntity(xField));
                        yList.Add(source.GetValueFromEntity(yField));
                    }
                    cachedChart.AddSeries(chartEntity.Title,
                                          chartEntity.ChartType.ToString(),
                                          xValue: xList,
                                          yValues: yList);
                }
                cachedChart.SaveToCache(chartEntity.CacheKey, chartEntity.CacheMinutes, slidingExpiration: false);
            }
            else
            {
                cachedChart = Chart.WriteFromCache(chartEntity.CacheKey);
            }
            return cachedChart.Write();
        }
    }
}
